#include "biosignal.h"
#include "reader.h"

#include "dataframeiterator.h"

#include "configuration.h"

#include <iostream>
#include <fstream>
#include <sstream>

using namespace std;

namespace biosignal {

#define MAX(a,b) (a>b ? a : b)
#define MIN(a,b) (a<b ? a : b)

BioSignal::BioSignal(const char* file_name) {
    file_name_ = file_name;
}

BioSignal::~BioSignal() {
    cout << "deleted biosignal" << endl;
}

void BioSignal::add_signals_info(std::list<SourceSignal*> signals) {
    std::list<SourceSignal*>::const_iterator it;
    for (it = signals.begin(); it != signals.end(); ++it) {
        SourceSignal::SourceSignal_sptr ptr(*it);
        m_signals_group.push_back(ptr);
    }
}

const SignalsGroup& BioSignal::signals_group() const {
    return (m_signals_group);
}


SignalSlice BioSignal::signal_slice(TimeOffset start, TimeOffset end) const
throw (BadTimePeriod) {
    TimePeriod time_period(m_recording_time.begin() + start,
                           m_recording_time.begin() + end);
    return signal_slice(time_period);
}

//TODO modify to actually return only the requested time period
SignalSlice BioSignal::signal_slice(TimePeriod time_period) const
throw (BadTimePeriod) {
    if (m_recording_time.contains(time_period)) {
        SignalSlice slice(this, time_period, ref_montage());
        return slice;
    } else {
        cerr << "selected time_period : " << time_period
             << "  signal recording : " << recording_time() << endl;
        throw BadTimePeriod();
    }
}

shared_ptr<const montage::Montage> BioSignal::ref_montage() const {
    montage::ReferentialMontage* ref_mon = new montage::ReferentialMontage( this );
    shared_ptr<const montage::Montage> montage(ref_mon);
    return montage;
}

//TODO: implement this
shared_ptr<const montage::Montage> BioSignal::avg_ref_montage() const {
}


TimePeriod BioSignal::recording_time() const {
    return m_recording_time;
}

SignalSlice BioSignal::signal() const {
    SignalSlice slice( this, recording_time() );
    return slice;
}

const BioSignal* load(string file_name) {
    ReaderRegistry& reader_registry(ReaderRegistry::get());
    return reader_registry.load(file_name);
}

string version() {
    return BIOSIGNAL_VERSION;
}

}
